package xyz.bali16.module.notification.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.starblues.annotation.Supplier;
import com.google.common.base.Preconditions;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import xyz.bali16.application.core.exception.BusinessException;
import xyz.bali16.application.core.utils.TimeUtil;
import xyz.bali16.application.entity.User;
import xyz.bali16.module.notification.entity.Notification;
import xyz.bali16.module.notification.entity.NotificationDTO;
import xyz.bali16.module.notification.enums.NotificationStatusEnum;
import xyz.bali16.module.notification.enums.NotificationTypeEnum;
import xyz.bali16.module.notification.mapper.NotificationMapper;
import xyz.bali16.module.notification.model.NotificationAddParam;
import xyz.bali16.module.notification.model.NotificationPageParam;
import xyz.bali16.module.notification.model.NotificationUpdateParam;

import java.util.List;
import java.util.Objects;

/**
 * @author bali2 on 9/3/2023.
 * @version 1.0
 */
@Service
@Supplier("notification")
public class NotificationServiceImpl extends ServiceImpl<NotificationMapper, Notification> implements NotificationService {
    private final NotificationMapper notificationMapper;

    public NotificationServiceImpl(NotificationMapper notificationMapper) {
        this.notificationMapper = notificationMapper;
    }

    @Override
    public IPage<Notification> getPage(NotificationPageParam param) {
        IPage<Notification> page = new Page<>(param.getCurrent(), param.getSize());
        return this.baseMapper.getPage(page, param);
    }

    @Override
    public void add(NotificationAddParam param) throws Exception {
        Preconditions.checkNotNull(param, "NotificationAddParam 参数不能为为空");
        Notification notification = new Notification();
        BeanUtils.copyProperties(param, notification);
        System.out.println(notification);
        save(notification);
    }

    @Override
    public void update(NotificationUpdateParam param) throws Exception {
        Preconditions.checkNotNull(param, "NotificationAddParam 参数不能为为空");
        Notification notification = new Notification();
        BeanUtils.copyProperties(param, notification);
        updateById(notification);
    }

    @Override
    public void updateStatus(String notificationId, Integer status) throws Exception {
        Preconditions.checkNotNull(notificationId, "消息id不能为空");
        if (status == null) {
            return;
        }
        Notification notification = new Notification();
        notification.setStatus(status);
        updateById(notification);
    }

    @Override
    public void delete(String notificationId) throws Exception {
        if (notificationId == null) {
            return;
        }
        removeById(notificationId);

    }

    @Override
    public Integer unreadCount(String userId) {
        Wrapper<Notification> wrapper = Wrappers.<Notification>lambdaQuery().eq(Notification::getReceiverId,userId);
        return count(wrapper);
    }

    @Override
    public NotificationDTO read(String id, User user) throws Exception{
        Notification notification = getById(id);
        if (notification == null) {
            throw new BusinessException("找不到消息");
        }
        if (!Objects.equals(notification.getReceiverId(), user.getUserId())) {//接受者并不是当前用户
            throw new BusinessException("不可阅读他人信息");
        }
        notification.setStatus(NotificationStatusEnum.READ.getStatus());
        notificationMapper.updateById(notification);
        NotificationDTO notificationDTO = new NotificationDTO();
        BeanUtils.copyProperties(notification, notificationDTO);
        notificationDTO.setTypeName(NotificationTypeEnum.nameOfType(notification.getType()));
        return  notificationDTO;
    }

    @Override
    public void removeAllByUserId(String userId) {
        Wrapper<Notification> wrapper = Wrappers.<Notification>lambdaQuery().eq(Notification::getReceiverId,userId);
        remove(wrapper);
    }

    @Override
    public void readAllByUserId(String userId) {
        Wrapper<Notification> wrapper = Wrappers.<Notification>lambdaQuery().eq(Notification::getReceiverId,userId);
        List<Notification> notifications = list(wrapper);
        for(Notification notification : notifications){
            notification.setStatus(NotificationStatusEnum.READ.getStatus());
        }
        updateBatchById(notifications);
    }

    @Override
    @Supplier.Method("createNotify")
    public void createNotify(String notifierId, String receiverId, String notifierName, String outerTitle, NotificationTypeEnum notificationType, String outerId) {

        Notification notification = new Notification();
        notification.setGmtCreate(TimeUtil.getNowTimeToSeconds());
        notification.setType(notificationType.getType());
        notification.setOuterId(outerId);
        notification.setNotifierName(notifierName);
        notification.setStatus(NotificationStatusEnum.UNREAD.getStatus());
        notification.setNotifierId(notifierId);
        notification.setReceiverId(receiverId);
        notification.setNotifierName(notifierName);
        notification.setOuterTitle(outerTitle);
        notificationMapper.insert(notification);

    }

}
